using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.InteropServices;

namespace OgilvyOne.Utility
{
    public enum Store { Machine = 1, User = 2 };

    /// <summary>
    /// The DSAPI wrapper
    /// To be released as part of the Microsoft Configuration Building Block
    /// </summary>
    public class DataProtector
    {
        // Fields
        private const int CRYPTPROTECT_LOCAL_MACHINE = 4;
        private const int CRYPTPROTECT_UI_FORBIDDEN = 1;
        private static IntPtr NullPtr;
        private Store store;

        // Methods
        static extern DataProtector();
        public extern DataProtector(Store tempStore);
        [DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool CryptProtectData(ref DATA_BLOB pDataIn, string szDataDescr, ref DATA_BLOB pOptionalEntropy, IntPtr pvReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, int dwFlags, ref DATA_BLOB pDataOut);
        [DllImport("Crypt32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        private static extern bool CryptUnprotectData(ref DATA_BLOB pDataIn, string szDataDescr, ref DATA_BLOB pOptionalEntropy, IntPtr pvReserved, ref CRYPTPROTECT_PROMPTSTRUCT pPromptStruct, int dwFlags, ref DATA_BLOB pDataOut);
        public extern byte[] Decrypt(byte[] cipherText, byte[] optionalEntropy);
        public extern byte[] Encrypt(byte[] plainText, byte[] optionalEntropy);
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        private static extern unsafe int FormatMessage(int dwFlags, ref IntPtr lpSource, int dwMessageId, int dwLanguageId, ref string lpBuffer, int nSize, IntPtr* Arguments);
        private static extern string GetErrorMessage(int errorCode);
        private extern void InitPromptstruct(ref CRYPTPROTECT_PROMPTSTRUCT ps);

        // Nested Types
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        internal struct CRYPTPROTECT_PROMPTSTRUCT
        {
            public int cbSize;
            public int dwPromptFlags;
            public IntPtr hwndApp;
            public string szPrompt;
        }

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        internal struct DATA_BLOB
        {
            public int cbData;
            public IntPtr pbData;
        }

    }
}
